import axios, {
  AxiosHeaders,
  type AxiosInstance,
  type AxiosRequestConfig,
  type AxiosResponse,
} from 'axios'
import { store } from '../store'
import { resetUser } from '../store/slices/userSlice'

// 基础配置
const BASE_URL = '/api'
const REQUEST_TIMEOUT = 60000

// 从环境变量读取平台侧配置
const TENANT_ID = (import.meta as any).env?.VITE_TENANT_ID || '000000'
// Basic 认证已在拦截器中写死，如需改回动态读取可恢复下两行
// const CLIENT_ID = (import.meta as any).env?.VITE_CLIENT_ID || 'saber'
// const CLIENT_SECRET = (import.meta as any).env?.VITE_CLIENT_SECRET || 'saber_secret'

// 后端 envelope 统一在拦截器中解析，导出的方法直接返回数据部分 T

// function base64Encode(input: string) {
//   try {
//     return btoa(unescape(encodeURIComponent(input)))
//   } catch {
//     return ''
//   }
// }

function showToast(message: string) {
  try {
    // 动态引入，避免首屏体积增加
    // eslint-disable-next-line @typescript-eslint/no-var-requires
    const { Toast } = require('antd-mobile')
    Toast.show({ content: message })
  } catch {
    if (typeof window !== 'undefined') {
      window.alert(message)
    }
  }
}

function getCurrentPath() {
  if (typeof window === 'undefined') return '/'
  const { hash, pathname, search } = window.location
  // Hash 路由：# 后面才是实际路由
  if (hash && hash.startsWith('#/')) {
    return hash.slice(1)
  }
  // 非 hash 模式
  return `${pathname}${search || ''}`
}

function handle401() {
  // 清理登录状态
  store.dispatch(resetUser())
  const current = getCurrentPath()
  if (typeof window !== 'undefined') {
    // 避免在登录页重复跳转
    if (!/\/login(\?|$)/.test(current)) {
      const redirect = encodeURIComponent(current)
      // 兼容 HashRouter，直接设置 hash
      const targetHash = `#/login?redirect=${redirect}`
      if (window.location.hash !== targetHash) {
        window.location.hash = targetHash
      }
    }
  }
}

// 创建 axios 实例
const http: AxiosInstance = axios.create({
  baseURL: BASE_URL,
  timeout: REQUEST_TIMEOUT,
})

// 请求拦截：附加 Token 与公共头
http.interceptors.request.use(
  config => {
    const state = store.getState()
    const token = state.user.token

    // 规范方式设置 headers，避免类型不匹配
    const headers = new AxiosHeaders(config.headers)
    headers.set('Blade-Requested-With', 'BladeHttpRequest')
    headers.set('Tenant-Id', String(TENANT_ID))
    headers.set('Authorization', 'Basic c2FiZXI6c2FiZXJfc2VjcmV0')
    if (token) headers.set('Blade-Auth', `bearer ${token}`)
    config.headers = headers
    return config
  },
  error => Promise.reject(error),
)

// 响应拦截：统一业务 envelope 与错误提示
http.interceptors.response.use(
  (response: AxiosResponse<any>) => {
    const { status, statusText, data } = response
    console.log('[response]', response)
    if (status >= 200 && status < 400) {
      // 处理后端通用 envelope
      if (data && typeof data === 'object' && 'code' in data) {
        const code = data.code as number | undefined
        const success = (data && data.success) as boolean | undefined
        console.log('[code]', code)
        console.log('[success]', success)
        if (code === 401) {
          handle401()
          return Promise.reject(new Error('未登录或凭证过期'))
        }
        const isSuccess = success === true || code === 0 || code === 200
        if (isSuccess) {
          // 业务成功：返回 data 字段内容
          return data.data
        }
        const msg = (data && data.msg) || '请求失败'
        showToast(msg)
        return Promise.reject(new Error(msg))
      }
      // 非 envelope：直接返回
      return data
    }
    showToast(`${status}-${statusText}`)
    return Promise.reject(new Error(`${status}-${statusText}`))
  },
  error => {
    const msg = String(error && (error.message || error))
    if (/502|503|504/.test(msg) || msg.includes('timeout')) {
      const tip = '系统繁忙，正在为您排队中，请稍后再试'
      showToast(tip)
      return Promise.reject(new Error(tip))
    }
    const status = error?.response?.status
    if (status === 401) {
      handle401()
      return Promise.reject(new Error('未登录或凭证过期'))
    }
    const serverMsg = error?.response?.data?.msg
    const tip = serverMsg || '网络异常，请点击重试'
    showToast(tip)
    return Promise.reject(new Error(tip))
  },
)

// 对外导出便捷方法
export function get<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {
  return http.get(url, config)
}

export function post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
  return http.post(url, data, config)
}

// POST 且将参数追加在查询串上（无请求体）
export function postForm<T = any>(
  url: string,
  params?: any,
  config?: AxiosRequestConfig,
): Promise<T> {
  const mergedConfig: AxiosRequestConfig = { ...(config || {}) }
  mergedConfig.params = { ...(config?.params as any), ...(params || {}) }
  return http.post(url, undefined, mergedConfig)
}

export function put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
  return http.put(url, data, config)
}

export function del<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {
  return http.delete(url, config)
}

export default http
